<script setup lang="tsx">
import { ref } from 'vue';
import { Button, Popconfirm, Tag } from 'ant-design-vue';
import type { Ref } from 'vue';
import { useBoolean } from '@sa/hooks';
import { fetchDeleteMenu, fetchGetAllPages, fetchGetMenuList } from '@/service/api';
import { useTable, useTableOperate, useTableScroll } from '@/hooks/common/table';
import { $t } from '@/locales';
import { yesOrNoRecord } from '@/constants/common';
import { enableStatusRecord, menuTypeRecord } from '@/constants/business';
import SvgIcon from '@/components/custom/svg-icon.vue';
import TableHeaderOperation from '@/components/advanced/table-header-operation.vue';
import { useRouteStore } from '@/store/modules/route';
import { useAuth } from '@/hooks/business/auth';
import MenuOperateModal from './modules/menu-operate-modal.vue';
import MenuViewDrawer from './modules/menu-view-drawer.vue';

type OperateType = AntDesign.TableOperateType | 'addChild';

const { bool: visible, setTrue: openModal } = useBoolean();
const { tableWrapperRef, scrollConfig } = useTableScroll();
const routeStore = useRouteStore();
const { hasAuthSync } = useAuth();

// 自定义API函数来处理后端返回的数据格式
async function customFetchGetMenuList(params?: Api.SystemManage.RoleSearchParams) {
  try {
    const response = await fetchGetMenuList(params);
    // console.log('菜单列表响应:', response);

    let menuRecords: Api.SystemManage.Menu[] = [];
    let total = 0;
    let current = 1;
    let size = 10;

    // 检查是否是FlatResponseData格式
    if (response && typeof response === 'object' && 'data' in response && 'error' in response) {
      // 这是FlatResponseData格式，需要检查是否有错误
      if (response.error) {
        throw new Error((response.error as any)?.message || '获取菜单列表失败');
      }

      // 从response.data中提取数据
      const data = (response as any).data;
      if (data && typeof data === 'object' && 'records' in data && Array.isArray(data.records)) {
        menuRecords = data.records;
        total = data.total || menuRecords.length;
        current = data.current || 1;
        size = data.size || menuRecords.length;
      } else if (Array.isArray(data)) {
        menuRecords = data;
        total = menuRecords.length;
      } else {
        console.error('意外的数据格式:', data);
        throw new Error('获取菜单列表失败：数据格式错误');
      }
    }
    // 如果response直接是MenuList类型（经过拦截器处理）
    else if (
      response &&
      typeof response === 'object' &&
      'records' in response &&
      Array.isArray((response as any).records)
    ) {
      menuRecords = (response as any).records;
      total = (response as any).total || menuRecords.length;
      current = (response as any).current || 1;
      size = (response as any).size || menuRecords.length;
    }
    // 如果response直接是数组（兼容其他情况）
    else if (Array.isArray(response)) {
      menuRecords = response;
      total = menuRecords.length;
    } else {
      console.error('意外的响应格式:', response);
      throw new Error('获取菜单列表失败：响应格式错误');
    }

    // 返回符合 TableApiFn 期望的 FlatResponseData 格式
    return {
      data: {
        records: menuRecords,
        total,
        current,
        size
      },
      error: null,
      response: response as any
    };
  } catch (error) {
    console.error('获取菜单列表错误:', error);
    // 创建一个模拟的AxiosError和AxiosResponse
    const mockResponse = {
      data: null,
      status: 500,
      statusText: 'Internal Server Error',
      headers: {},
      config: {}
    } as any;

    const axiosError = {
      message: error instanceof Error ? error.message : '获取菜单列表失败',
      code: 'ERROR',
      response: mockResponse
    } as any;

    return {
      data: null,
      error: axiosError,
      response: mockResponse
    };
  }
}

const { columns, columnChecks, data, loading, pagination, getData, getDataByPage } = useTable({
  apiFn: customFetchGetMenuList,
  columns: () => [
    {
      key: 'id',
      title: $t('page.manage.menu.id'),
      align: 'center',
      dataIndex: 'id'
    },
    {
      key: 'menuType',
      title: $t('page.manage.menu.menuType'),
      align: 'center',
      width: 80,
      customRender: ({ record }) => {
        const tagMap: Record<Api.SystemManage.MenuType, string> = {
          '1': 'default',
          '2': 'processing'
        };

        const label = $t(menuTypeRecord[record.menuType as keyof typeof menuTypeRecord]);

        return <Tag color={tagMap[record.menuType as keyof typeof tagMap]}>{label}</Tag>;
      }
    },
    {
      key: 'menuName',
      title: $t('page.manage.menu.menuName'),
      align: 'center',
      minWidth: 120,
      customRender: ({ record }) => {
        const { i18nKey, menuName } = record;

        const label = i18nKey ? $t(i18nKey) : menuName;

        return <span>{label}</span>;
      }
    },
    {
      key: 'icon',
      title: $t('page.manage.menu.icon'),
      align: 'center',
      width: 60,
      customRender: ({ record }) => {
        const icon = record.iconType === '1' ? record.icon : undefined;

        const localIcon = record.iconType === '2' ? record.icon : undefined;

        return (
          <div class="flex-center">
            <SvgIcon icon={icon} localIcon={localIcon} class="text-icon" />
          </div>
        );
      }
    },
    {
      key: 'routeName',
      title: $t('page.manage.menu.routeName'),
      align: 'center',
      dataIndex: 'routeName',
      minWidth: 120
    },
    {
      key: 'routePath',
      title: $t('page.manage.menu.routePath'),
      align: 'center',
      dataIndex: 'routePath',
      minWidth: 120
    },
    {
      key: 'status',
      title: $t('page.manage.menu.menuStatus'),
      align: 'center',
      width: 80,
      customRender: ({ record }) => {
        if (record.status === null) {
          return null;
        }

        const tagMap: Record<Api.Common.EnableStatus, string> = {
          '1': 'success',
          '2': 'warning'
        };

        const label = $t(enableStatusRecord[record.status as keyof typeof enableStatusRecord]);

        return <Tag color={tagMap[record.status as keyof typeof tagMap]}>{label}</Tag>;
      }
    },
    {
      key: 'hideInMenu',
      title: $t('page.manage.menu.hideInMenu'),
      dataIndex: 'hideInMenu',
      align: 'center',
      width: 80,
      customRender: ({ record }) => {
        const hide: CommonType.YesOrNo = record.hideInMenu ? 'Y' : 'N';

        const tagMap: Record<CommonType.YesOrNo, string> = {
          Y: 'error',
          N: 'default'
        };

        const label = $t(yesOrNoRecord[hide]);

        return <Tag color={tagMap[hide]}>{label}</Tag>;
      }
    },
    {
      key: 'parentId',
      dataIndex: 'parentId',
      title: $t('page.manage.menu.parentId'),
      width: 90,
      align: 'center'
    },
    {
      key: 'orderNum',
      dataIndex: 'orderNum',
      title: $t('page.manage.menu.order'),
      align: 'center',
      width: 60
    },
    {
      key: 'operate',
      title: $t('common.operate'),
      align: 'center',
      width: 280,
      customRender: ({ record }) => {
        const buttons = [];

        // 查看按钮（需要MENU_VIEW权限）
        if (hasAuthSync('MENU_VIEW')) {
          buttons.push(
            <Button type="primary" ghost size="small" onClick={() => handleView(record)}>
              {$t('common.view')}
            </Button>
          );
        }

        // 添加子菜单按钮（需要MENU_ADD权限）
        if (record.menuType === '1' && hasAuthSync('MENU_ADD')) {
          buttons.push(
            <Button type="primary" ghost size="small" onClick={() => handleAddChildMenu(record)}>
              {$t('page.manage.menu.addChildMenu')}
            </Button>
          );
        }

        // 编辑按钮（需要MENU_EDIT权限）
        if (hasAuthSync('MENU_EDIT')) {
          buttons.push(
            <Button type="primary" ghost size="small" onClick={() => handleEdit(record)}>
              {$t('common.edit')}
            </Button>
          );
        }

        // 删除按钮（需要MENU_DELETE权限）
        if (hasAuthSync('MENU_DELETE')) {
          buttons.push(
            <Popconfirm title={$t('common.confirmDelete')} onConfirm={() => handleDelete(Number(record.id))}>
              <Button danger ghost size="small">
                {$t('common.delete')}
              </Button>
            </Popconfirm>
          );
        }

        // 如果没有权限，显示无权限提示
        if (buttons.length === 0) {
          return <span class="text-sm text-gray-400">无操作权限</span>;
        }

        return <div class="flex-center justify-end gap-8px">{buttons}</div>;
      }
    }
  ]
});

const { checkedRowKeys, rowSelection, onBatchDeleted, onDeleted } = useTableOperate(data, getData);

const operateType = ref<OperateType>('add');

// 查看功能状态
const viewDrawerVisible = ref(false);
const viewingData = ref<Api.SystemManage.Menu | null>(null);

function handleAdd() {
  operateType.value = 'add';
  openModal();
}

async function handleBatchDelete() {
  // 批量删除功能可以后续实现
  window.$message?.warning('批量删除功能待实现');
  onBatchDeleted();
}

async function handleDelete(id: number) {
  try {
    const { error: err } = await fetchDeleteMenu(id);
    if (!err) {
      onDeleted();
    }
  } catch (error) {
    window.$message?.error(`删除失败：${(error as any).message}`);
  }
}

/** the edit menu data or the parent menu data when adding a child menu */
const editingData: Ref<Api.SystemManage.Menu | null> = ref(null);

function handleEdit(item: Api.SystemManage.Menu) {
  operateType.value = 'edit';
  editingData.value = { ...item };

  openModal();
}

function handleAddChildMenu(item: Api.SystemManage.Menu) {
  operateType.value = 'addChild';

  editingData.value = { ...item };

  openModal();
}

// 查看菜单详情
function handleView(record: Api.SystemManage.Menu) {
  viewingData.value = record;
  viewDrawerVisible.value = true;
}

const allPages = ref<string[]>([]);

async function getAllPages() {
  try {
    const response = await fetchGetAllPages();
    if (Array.isArray(response)) {
      allPages.value = response;
    } else {
      allPages.value = [];
    }
  } catch (error) {
    console.error('获取页面列表失败:', error);
    allPages.value = [];
  }
}
const dynamicMenuLoading = ref(false);
async function testDynamicMenu() {
  try {
    dynamicMenuLoading.value = true;
    await routeStore.initAuthRoute();
    dynamicMenuLoading.value = false;
    window.$message?.success('动态菜单加载成功！请查看左侧菜单栏');
  } catch (error) {
    window.$message?.error(`动态菜单加载失败：${(error as any).message}`);
    dynamicMenuLoading.value = false;
  }
}

function init() {
  getAllPages();
}

// init
init();
</script>

<template>
  <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
    <ACard
      :title="$t('page.manage.menu.title')"
      :bordered="false"
      :body-style="{ flex: 1, overflow: 'hidden' }"
      class="flex-col-stretch sm:flex-1-hidden card-wrapper"
    >
      <template #extra>
        <div class="flex-center gap-8px">
          <Button type="primary" size="small" :loading="dynamicMenuLoading" @click="testDynamicMenu">
            更新动态菜单
          </Button>
          <TableHeaderOperation
            v-model:columns="columnChecks"
            :disabled-delete="checkedRowKeys.length === 0"
            :loading="loading"
            add-permission="MENU_ADD"
            delete-permission="MENU_DELETE"
            @add="handleAdd"
            @delete="handleBatchDelete"
            @refresh="getData"
          />
        </div>
      </template>
      <ATable
        ref="tableWrapperRef"
        :columns="columns"
        :data-source="data"
        :row-selection="rowSelection"
        size="small"
        :loading="loading"
        row-key="id"
        :scroll="scrollConfig"
        :pagination="pagination"
        class="h-full"
      />
      <MenuOperateModal
        v-model:open="visible"
        :operate-type="operateType"
        :row-data="editingData"
        :all-pages="allPages"
        @submitted="getDataByPage"
      />

      <!-- 查看菜单详情抽屉 -->
      <MenuViewDrawer v-model:model-value="viewDrawerVisible" title="查看菜单详情" :width="600">
        <div v-if="viewingData" class="menu-view-content">
          <ARow :gutter="16">
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">菜单名称：</label>
                <span class="info-value">{{ viewingData.menuName }}</span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">菜单类型：</label>
                <span class="info-value">
                  <ATag v-if="viewingData.menuType" :color="viewingData.menuType === '1' ? 'default' : 'processing'">
                    {{ viewingData.menuType === '1' ? '目录' : '页面' }}
                  </ATag>
                  <span v-else>-</span>
                </span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">路由名称：</label>
                <span class="info-value">{{ viewingData.routeName || '-' }}</span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">路由路径：</label>
                <span class="info-value">{{ viewingData.routePath || '-' }}</span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">父级菜单：</label>
                <span class="info-value">{{ viewingData.parentId || '顶级菜单' }}</span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">排序：</label>
                <span class="info-value">{{ viewingData.orderNum || '-' }}</span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">状态：</label>
                <span class="info-value">
                  <ATag v-if="viewingData.status" :color="viewingData.status === '1' ? 'success' : 'warning'">
                    {{ viewingData.status === '1' ? '启用' : '禁用' }}
                  </ATag>
                  <span v-else>-</span>
                </span>
              </div>
            </ACol>
            <ACol :span="12">
              <div class="info-item">
                <label class="info-label">隐藏菜单：</label>
                <span class="info-value">
                  <ATag
                    v-if="viewingData.hideInMenu !== undefined"
                    :color="viewingData.hideInMenu ? 'error' : 'default'"
                  >
                    {{ viewingData.hideInMenu ? '是' : '否' }}
                  </ATag>
                  <span v-else>-</span>
                </span>
              </div>
            </ACol>
            <ACol :span="24">
              <div class="info-item">
                <label class="info-label">图标：</label>
                <span class="info-value">
                  <SvgIcon
                    v-if="viewingData.icon"
                    :icon="viewingData.iconType === '1' ? viewingData.icon : undefined"
                    :local-icon="viewingData.iconType === '2' ? viewingData.icon : undefined"
                    class="text-icon"
                  />
                  <span v-else>-</span>
                </span>
              </div>
            </ACol>
          </ARow>
        </div>
      </MenuViewDrawer>
    </ACard>
  </div>
</template>

<style scoped>
.menu-view-content {
  padding: 16px 0;
}

.info-item {
  margin-bottom: 16px;
  display: flex;
  align-items: center;
}

.info-label {
  font-weight: 500;
  color: #666;
  min-width: 80px;
  margin-right: 8px;
}

.info-value {
  color: #333;
  flex: 1;
}

/* 夜间模式样式 */
.dark .info-label {
  color: rgba(255, 255, 255, 0.65);
}

.dark .info-value {
  color: rgba(255, 255, 255, 0.85);
}
</style>
